package com.fingard.dsp.bank.directbank.fuiou01;

import java.io.File;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.util.*;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.gfgs01.GFGS01Header;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.util.FtpUtil;
import com.fingard.xml.XmlTextWriter;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.fingard.crypto.DigestHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.SortHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;

import javax.net.ssl.SSLContext;

public class FUIOU01Base extends DirectBase {
    protected String getCharset() {
        return getBankConfig().getCharset("utf-8");
    }

    /**
     * 提交富友代收付平台
     * @param p_for  提交地址
     * @param p_reqMap 请求参数
     * @return
     * @throws Exception
     */
    protected String[] sendToBank(String p_for, Map<String,String> p_reqMap) throws Exception{
        String[] retStr = new String[]{"",""};

        WriteBankUrlLogLn(bankFront.getUrl(p_for));

        String p_reqStr = "";
        for (Map.Entry<String, String> m : p_reqMap.entrySet()) {
            if (!p_reqStr.equals("")) {
                p_reqStr += "&";
            }
            p_reqStr += m.getKey() +"=" + m.getValue();
        }

        WriteBankLogStep2(p_reqStr);

        WebRequest tmpWebRequest = new WebRequest(bankFront.getUrl(p_for));
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("connection", "Close");

        byte[] tmpUpBytes = p_reqStr.getBytes(getCharset());
        retStr = tmpWebRequest.upload(tmpUpBytes, getCharset());
        WriteBankLogStep3(retStr[1]);

        return retStr;
    }

    protected String[] sendToBank(String p_for, String p_reqStr,boolean a) throws Exception{
        String[] retStr = new String[]{"",""};
        WriteBankUrlLogLn(bankFront.getUrl(p_for));
        WriteBankLogStep2(p_reqStr);

        WebRequest tmpWebRequest = new WebRequest(bankFront.getUrl(p_for));
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("connection", "Close");
        tmpWebRequest.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        if("Receipt".equals(p_for)){
            p_reqStr = "xml="+URLEncoder.encode(p_reqStr,getCharset());
        }else{
            p_reqStr = "tag="+URLEncoder.encode(p_reqStr,getCharset());//a=b&a1=b1&..
        }
        byte[] tmpUpBytes = p_reqStr.getBytes(getCharset());
        retStr = tmpWebRequest.upload(tmpUpBytes, getCharset());
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }


    protected String[] sendToBank(String p_for, String p_reqStr) throws Exception{
        String[] retStr = new String[]{"",""};
        WriteBankUrlLogLn(bankFront.getUrl(p_for));
        WriteBankLogStep2(p_reqStr);

        WebRequest tmpWebRequest = new WebRequest(bankFront.getUrl(p_for));
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("Connection", "close");
        tmpWebRequest.setRequestProperty("Content-Type","application/json");

        byte[] tmpUpBytes = p_reqStr.getBytes(getCharset());
        retStr = tmpWebRequest.upload(tmpUpBytes, getCharset());
        WriteBankLogStep3(retStr[1]);

        return retStr;
    }
    protected String get_nonce_str() throws Exception{
        String time_stamp = DateHelper.getSecsFrom1970();
        //随机字符串 String(32)
        Random random=new Random();
        long randLong = random.nextLong();
        randLong = random.nextLong();
        String nonce_str = time_stamp+String.format("%20d", randLong);
        nonce_str = DigestHelper.cryptoMD5RetHexStr(nonce_str.getBytes());
        return nonce_str;
    }

    protected String selectReceipt(String actNum,String date) throws Exception{
        StringBuilder stringBuilder = new StringBuilder();//记录流水号
        //String[] respHeader = new String[]{"", ""};
        String respCode = "";
        String respInfo = "";
        String ftpFileContent="";
        try {
            FtpSet ftpSet = bankFront.getFtpSet("transaction");
            ActSetItem actItem = getBankConfig().getActSetItem(actNum, "Transaction");
            if (actItem != null&&actItem!=null) {
                // FTP服务器配置信息
                String ftpHost = getBankConfig().getMapValueByKey("ftpMapping", "ftpHost");
                int ftpPort = Integer.parseInt(getBankConfig().getMapValueByKey("ftpMapping", "ftpPort"));

                // FTP登录用户信息
                String ftpUserName = getBankConfig().getMapValueByKey("ftpMapping", "ftpUserName");
                String ftpPassword = getBankConfig().getMapValueByKey("ftpMapping", "ftpPassword");

                // 对账单文件所在目录
                String ftpPath = getBankConfig().getMapValueByKey("ftpMapping", "ftpPayPath");
                ftpPath = ftpPath + "/" + date + "/";
                // 本地路径
                String localPath = getBankConfig().getMapValueByKey("ftpMapping", "localPath");
                String fileName = actItem.merchantId + "_" + date + ".txt";
                // 从FTP下载对账单
                //FtpUtil.downloadFtpFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, localPath, fileName);
                // 从本地文件读取对账单数据
                String filePath2 = localPath + File.separator + fileName;
                String posRecRequestType = getBankConfig().getValueAsString("requestType");

                if ("ftp".equals(posRecRequestType.toLowerCase())) {
                    FtpUtil.downloadFtpFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, localPath, fileName);
                    String filePath1 = localPath + File.separator + fileName;
                    ftpFileContent = FtpUtil.getTextFromFile(filePath1, "GBK");
                } else if ("sftp".equals(posRecRequestType.toLowerCase())) {
                    SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
                    localPath = localPath + File.separator + fileName;
                    ftpPath=ftpPath+fileName;
                    WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + ftpPath);
                    FtpReceiver ftpReceiver = sftpPortClient.downloadFile("/account",ftpPath, localPath);
                    if (ftpReceiver.isCompleted) {
                        if (ftpFileContent.length() > 0) {
                            ftpFileContent=ftpFileContent+"\n";
                        }
                        ftpFileContent= FileHelper.readFileText(localPath, "GBK");
                    } else {
                        respCode = "-1";
                        respInfo = "对账单下载失败,原因:\r\n" + ftpReceiver.connMsg;
                    }
                }
                //String ftpFileContent = FtpUtil.getTextFromFile(filePath2, "GBK");
                // 返回对账单文件数据
                //ftpFileContent = new String(ftpFileContent.getBytes("gbk"),"utf-8");
                WriteBankLogLn("银行返回"+date+"的历史明细为:"+ftpFileContent);
                // 解析富友对账单
                //0业务代码|1交易来源|2交易流水号|3源交易流水号|4富友帐务流水号|5文件明细号|6交易提交时间|7商户复核时间|8交易发送时间|
                // 9交易类型|10文件名|11交易金额|12交易手续费|13户名|14扣款账号|15卡属性|16发卡机构|17收款账号|18注释|19企业流水号|20备注|21手机号
                String[] totalLine = ftpFileContent.split("\r\n");
                for (int i = 0; i < totalLine.length; i++) {
                    String[] values = totalLine[i].split("\\|");
                    //retDetail.askNumber = values[2];//交易流水号
                    if (values.length > 20&&"交易成功".equals(values[18].trim())) {
                        stringBuilder.append(values[19].trim()).append("|");
                    }
                }
            } else {
                //respHeader[0] = "-1";
                WriteBankLogStep3("未找到历史明细账号[" + actNum + "]商户配置信息");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            respCode = "-1";
            respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        WriteBankLogLn("查询到的明细流水的流水号为："+stringBuilder.toString());
        stringBuilder.append("|");
        return stringBuilder.toString();
    }

    public static String hex(String[] strs, String key){
        Arrays.sort(strs);//集合自动排序
        StringBuffer source = new StringBuffer();
        for(String str:strs){
            source.append(str).append("|");
        }
        String bigstr = source.substring(0,source.length()-1);

        System.out.println(bigstr);
        String result = DigestUtils.shaHex(DigestUtils.shaHex(bigstr)+"|"+key);

        return result;
    }

}
